import axios from 'axios';
import dotenv from 'dotenv';
import Redis from 'ioredis';

dotenv.config();

// 创建 Redis 客户端
const redis = new Redis({
  host: process.env.REDIS_HOST || 'localhost',
  port: process.env.REDIS_PORT || 6379,
  password: process.env.REDIS_PASSWORD || '',
  keyPrefix: 'story:'
});

// 预设的故事模板，在 API 调用失败时使用
const storyTemplates = [
  '从前，有一个叫{toyName}的可爱毛绒玩具。它有着柔软的绒毛和明亮的眼睛，总是带着温暖的微笑。{toyName}住在一个充满玩具的神奇商店里，每当夜幕降临，所有玩具都会苏醒过来，开始他们的冒险。\n\n一天晚上，{toyName}发现了一扇通往星空的小门。它鼓起勇气，踏上了一段奇妙的旅程。在星星的指引下，{toyName}结交了许多新朋友，还帮助了一颗迷路的小星星回家。\n\n当黎明到来时，{toyName}回到了商店，带着满满的快乐记忆。虽然白天它只是一个普通的毛绒玩具，但每个拥抱它的孩子都能感受到它传递的温暖和勇气。',
  
  '{toyName}是一个神奇的毛绒玩具，它有着柔软的触感和可爱的笑容。在一个月光明亮的夜晚，当小主人熟睡后，{toyName}悄悄地从床上跳下来，开始了它的秘密冒险。\n\n它来到了玩具王国，那里有各种各样的玩具朋友。{toyName}凭借着它善良的心和乐于助人的性格，很快成为了大家的好朋友。它帮助小熊找回了丢失的蜂蜜罐，陪伴孤独的布娃娃度过了难过的时光。\n\n每当清晨的阳光照进窗户，{toyName}就会悄悄地回到小主人身边，守护着他的梦想和快乐。虽然它不会说话，但它的爱和温暖一直陪伴着小主人成长。',
  
  '在一个充满魔法的玩具店里，住着一个名叫{toyName}的毛绒玩具。它有着最柔软的毛发和最闪亮的眼睛，是所有孩子都想拥有的好伙伴。\n\n有一天，一个小女孩带走了{toyName}，给了它一个温暖的家。每天晚上，当小女孩睡着后，{toyName}就会悄悄地守护在她身边，赶走所有可能出现的噩梦。\n\n在梦境中，{toyName}和小女孩一起探索奇妙的世界，一起飞越彩虹，一起与云朵做游戏。它教会了小女孩勇敢和坚强，也从小女孩那里学会了爱与分享。{toyName}不仅仅是一个玩具，更是小女孩最好的朋友和成长路上的守护者。'
];

class StoryService {
  constructor() {
    this.baseURL = 'https://api.siliconflow.cn/v1/chat/completions';
    this.token = process.env.SILICON_FLOW_TOKEN;
    this.cacheExpiry = 60 * 60 * 24 * 7; // 7天缓存
  }

  async generateStory(toyName) {
    try {
      // 尝试从缓存获取故事
      const cacheKey = `toy:${toyName}`;
      const cachedStory = await redis.get(cacheKey);
      
      if (cachedStory) {
        console.log(`从缓存获取故事，玩具名称: ${toyName}`);
        return {
          success: true,
          story: cachedStory,
          fromCache: true
        };
      }
      
      console.log(`缓存未命中，为 ${toyName} 生成新故事`);
      
      try {
        // 尝试从 AI 服务获取故事
        const story = await this.fetchStoryFromAI(toyName);
        
        // 将故事保存到缓存
        await redis.set(cacheKey, story, 'EX', this.cacheExpiry);
        console.log(`故事已缓存，键: ${cacheKey}`);
        
        return {
          success: true,
          story: story
        };
      } catch (aiError) {
        console.error('AI 服务调用失败，使用预设模板:', aiError.message);
        
        // 使用预设模板生成故事
        const templateIndex = Math.floor(Math.random() * storyTemplates.length);
        const template = storyTemplates[templateIndex];
        const fallbackStory = template.replace(/{toyName}/g, toyName);
        
        // 将预设故事也缓存起来，但缓存时间较短（1天）
        await redis.set(cacheKey, fallbackStory, 'EX', 60 * 60 * 24);
        
        return {
          success: true,
          story: fallbackStory,
          fromTemplate: true
        };
      }
    } catch (error) {
      console.error('故事生成错误:', {
        message: error.message
      });

      return {
        success: false,
        message: '故事生成失败，请稍后重试'
      };
    }
  }
  
  // 从 AI 服务获取故事
  async fetchStoryFromAI(toyName) {
    const prompt = `请为这个叫"${toyName}"的毛绒玩具创作一个有趣的短故事。要求:
1. 故事应该富有想象力和趣味性
2. 符合娃娃的用户群体
3. 故事长度在200字左右`;

    const requestData = {
      model: "deepseek-ai/DeepSeek-V3",
      stream: false,
      max_tokens: 512,
      temperature: 0.7,
      top_p: 0.7,
      top_k: 50,
      frequency_penalty: 0.5,
      n: 1,
      messages: [
        {
          role: "user",
          content: prompt
        }
      ]
    };

    console.log('发送故事生成请求:', {
      url: this.baseURL,
      model: requestData.model
    });

    const response = await axios({
      method: 'post',
      url: this.baseURL,
      headers: { 
        'Authorization': `Bearer ${this.token}`,
        'Content-Type': 'application/json'
      },
      data: requestData,
      timeout: 120000 // 减少超时时间，避免长时间等待
    });

    if (response.data?.choices?.[0]?.message?.content) {
      const story = response.data.choices[0].message.content;
      console.log('成功生成故事，长度:', story.length);
      return story;
    }

    throw new Error('无法从响应中获取故事内容');
  }
  
  // 清除特定玩具的故事缓存
  async clearStoryCache(toyName) {
    try {
      const cacheKey = `toy:${toyName}`;
      await redis.del(cacheKey);
      return true;
    } catch (error) {
      console.error('清除故事缓存失败:', error);
      return false;
    }
  }
  
  // 清除所有故事缓存
  async clearAllStoryCaches() {
    try {
      const keys = await redis.keys('toy:*');
      if (keys.length > 0) {
        await redis.del(keys);
      }
      return true;
    } catch (error) {
      console.error('清除所有故事缓存失败:', error);
      return false;
    }
  }
}

export default new StoryService(); 